#include <iostream>

using std::cout;
using std::endl;

//单例模式的设计需求：一个类只能创建一个对象（而不是一类对象）
//，对象不能有两个
//如何构思？
//创建的这个对象肯定是应该放在内存中。
//放在内存中那个位置？
//1、栈区,不行
//2、堆区,不行
//3、全局区,不行
//4、静态区,不行
//5、文字常量区,可以存放字符串常量
//6、程序代码区，二进制代码，肯定不行
//
//思路就陷入僵局了？好像都不行
//刚才的分析发现：所有的对象都是在类的外部进行创建，这就是
//他们的共同的特点，那么能不能在类的内部创建对象呢？
class Singleton
{
public:
    static Singleton *getInstance()
    {
        if(_pInstance == nullptr)
        {
            _pInstance = new Singleton();
        }
        return _pInstance;//创建对象
    }

    static void destroy()
    {
        if(_pInstance)
        {
            delete _pInstance;
            _pInstance = nullptr;
        }
    }

private:
    Singleton()
    {
        cout << "Singleton()" << endl;
    }
    ~Singleton()
    {
        cout << "~Singleton()" << endl;
    }
    
private:
    static Singleton *_pInstance ;
};

//静态数据成员需要在类外进行初始化
Singleton *Singleton::_pInstance = nullptr;

/* Singleton gS1;//全局对象,error */
/* Singleton gS2; */

/* static Singleton ss1;//静态对象,error */
/* static Singleton ss2; */

int main(int argc, char *argv[])
{
    Singleton *ps1 = Singleton::getInstance();
    Singleton *ps2 = Singleton::getInstance();
    Singleton *ps3 = Singleton::getInstance();
    printf("ps1 = %p\n", ps1);
    printf("ps2 = %p\n", ps2);
    printf("ps3 = %p\n", ps3);

    ps1->destroy();
    ps1->destroy();
    ps2->destroy();
    ps2->destroy();
    ps3->destroy();
    ps3->destroy();

    /* Singleton::getInstance(); */
    /* Singleton::destroy(); */

    /* delete ps1;//error,将析构函数设置为私有 */
    /* delete ps2;//error */
    /* delete ps3;//error */
    /* cout << "hello" << endl; */
    /* Singleton s1;//栈对象,error */
    /* Singleton s2; */
    /* printf("&gS1 = %p\n", &gS1); */
    /* printf("&gS2 = %p\n", &gS2); */
    /* printf("&ss1 = %p\n", &ss1); */
    /* printf("&ss2 = %p\n", &ss2); */
    /* printf("&s1 = %p\n", &s1); */
    /* printf("&s2 = %p\n", &s2); */

    /* Singleton *ps1 = new Singleton();//堆对象,error */
    /* Singleton *ps2 = new Singleton();//堆对象 */
    /* printf("ps1 = %p\n", ps1); */
    /* printf("ps2 = %p\n", ps2); */
    return 0;
}

